package com.ac.api.process_line.controller;

import com.ac.api.equipment.entity.Equipment;
import com.ac.api.equipment.service.EquipmentService;
import com.ac.api.process_history.service.ProcessHistoryService;
import com.ac.api.process_line.dao.ProcessLineMapper;
import com.ac.api.process_line.entity.LineVo;
import com.ac.api.process_task.entity.ProcessTask;
import com.ac.api.process_task.service.ProcessTaskService;
import com.ac.api.production_order.entity.ProductionOrder;
import com.ac.api.production_order.service.ProductionOrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.RequestMapping;
import com.base.annotation.SysLog;
import org.springframework.web.bind.annotation.RestController;
import com.base.helper.BaseController;
import com.base.helper.Result;
import com.ac.api.process_line.entity.ProcessLine;
import com.ac.api.process_line.service.ProcessLineService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 生产线信息表 前端控制器
 * </p>
 *
 * @author dc
 * @since 2025-06-11
 */
@Api(tags = "ProcessLine")
@RestController
@RequestMapping("/processLine")
public class ProcessLineController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(ProcessLineController.class);
    @Autowired
    private ProcessLineService entityService;
    @Autowired
    private ProcessTaskService processTaskService;
    @Autowired
    private ProductionOrderService productionOrderService;
    @Autowired
    private ProcessHistoryService processHistoryService;
    @Autowired
    private EquipmentService equipmentService;

    @SysLog(action = "findByPage", value = "分页查询生产线")
    @ApiOperation(value = "分页查询生产线", notes = "分页查询生产线")
    @GetMapping("/findByPage")
    @ApiImplicitParams({ @ApiImplicitParam(name = "size", value = "分页大小", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面：从1开始", paramType = "query") })
    public Result<IPage<ProcessLine>> findByPage(final ProcessLine example, final Page page) {
        IPage<ProcessLine> records = entityService.page(example, page);
        return new Result(true, records);
    }

    @SysLog(action = "delete", value = "删除生产线")
    @ApiOperation(value = "删除生产线")
    @DeleteMapping(value = "/delete/{id}")
    @ApiImplicitParam(name = "id", value = "生产线ID", required = true, paramType = "path")
    public Result delete(@PathVariable final Integer id) {
        try {
            // 清理关联设备和工序任务
            for (ProcessTask processTask : processTaskService.list(new QueryWrapper<ProcessTask>().eq("line_id", id))){
                for (Equipment equipment : equipmentService.list(new QueryWrapper<Equipment>().eq("production_task_id", processTask.getTaskId())))
                    equipmentService.updateById(equipment
                            .setProductionTaskId(0)
                            .setUpdatedAt(LocalDateTime.now())
                            .setStatus("停机") // 将关联设备置为停机状态
                    );
            }
            // 删除相关工序任务
            processTaskService.remove(new QueryWrapper<ProcessTask>().eq("task_id", id));
            // 删除生产线
            entityService.removeById(id);
            return new Result(true, "成功删除生产线", null);
        } catch (DataIntegrityViolationException e) {
            LOG.error("删除生产线失败", e);
            return new Result(false, "删除生产线失败", "该生产线不能删除，存在其他关联数据");
        } catch (Exception e) {
            LOG.error("删除生产线失败", e);
            return new Result(false, "删除生产线失败", e.getMessage());
        }
    }

    @SysLog(action = "one", value = "查询单个生产线")
    @ApiOperation(value = "查询单个生产线")
    @GetMapping(value = "/one/{id}")
    @ApiImplicitParam(name = "id", value = "生产线ID", required = true, paramType = "path")
    public Result one(@PathVariable final Integer id) {
        try {
            ProcessLine entity = entityService.getById(id);
            return new Result(true, entity);
        } catch (Exception e) {
            LOG.error("查询单个生产线失败", e);
            return new Result(false, new ProcessLine());
        }
    }

    @SysLog(action = "add", value = "添加生产线")
    @ApiOperation(value = "添加生产线")
    @PostMapping(value = "/add")
    public Result add(@Valid @RequestBody final ProcessLine entity, final BindingResult result) {
        try {
            if (result.hasErrors()) {
                Map<String, String> map = this.getErrors(result);
                String errorMsg = map.entrySet().iterator().next().getValue();
                return new Result(false, "保存生产线失败", errorMsg, map);
            } else {
                entityService.save(entity);
                return new Result(true, "成功保存生产线", null);
            }
        } catch (Exception e) {
            LOG.error("添加生产线失败", e);
            return new Result(false, "保存生产线失败", e.getMessage());
        }
    }

    @SysLog(action = "update", value = "修改生产线")
    @ApiOperation(value = "修改生产线")
    @PutMapping(value = "/update")
    public Result update(@Valid @RequestBody final ProcessLine entity, final BindingResult result) {
        try {
            if (result.hasErrors()) {
                Map<String, String> map = this.getErrors(result);
                String errorMsg = map.entrySet().iterator().next().getValue();
                return new Result(false, "修改生产线失败", errorMsg, map);
            } else {
                if (null == entity.getLineId()) {
                    throw new RuntimeException("id不能为空");
                }
                entityService.updateById(entity);
                return new Result(true, "成功修改生产线", null);
            }
        } catch (Exception e) {
            LOG.error("修改生产线失败", e);
            return new Result(false, "修改生产线失败", e.getMessage());
        }
    }

    @SysLog(action = "all", value = "查询全部生产线")
    @ApiOperation(value = "全部订单")  // 注意：实际是查询全部生产线
    @GetMapping(value = "/all")
    public Result<List<ProcessLine>> all(ProcessLine example) {
        List<ProcessLine> entitys = entityService.list(example);
        if (null != entitys) {
            return new Result<>(true, entitys);
        }
        return new Result<>(true, Collections.emptyList());
    }

    @SysLog(action = "running", value = "查询执行中的生产线")
    @ApiOperation(value = "正在执行中生产线列表")
    @GetMapping(value = "/running")
    public Result<List<ProcessLine>> running() {
        List<ProcessLine> entitys = entityService.running();
        if (null != entitys) {
            return new Result<>(true, entitys);
        }
        return new Result<>(true, Collections.emptyList());
    }

    @SysLog(action = "detail", value = "查看生产线详情")
    @ApiOperation(value = "查看生产线详情")
    @GetMapping("/detail/{id}")
    public Result<LineVo> detail(@PathVariable Integer id) {
        // 获取生产线基本信息
        ProcessLine entity = entityService.getById(id);
        // 获取生产线关联的工序任务
        List list = processTaskService.list(new QueryWrapper<ProcessTask>().eq("Line_id", id));
        // 组装生产线详情对象
        LineVo lineVo = new LineVo(entity.getLineId(), entity.getStartTime(), entity.getEndTime(), entity.getStatus(),
                entity.getCreatedAt(), entity.getUpdatedAt(), entity.getProductModel(), list);
        return new Result<>(true, lineVo);
    }

    @SysLog(action = "free", value = "查询空闲生产线")
    @ApiOperation(value = "获取空闲生产线")
    @GetMapping("/free")
    public Result<List<ProcessLine>> free() {
        // 查询状态为"待生产"的生产线
        List<ProcessLine> entitys = entityService.list(new QueryWrapper<ProcessLine>().eq("status", "待生产"));
        if (null != entitys) {
            return new Result<>(true, entitys);
        }
        return new Result<>(true, Collections.emptyList());
    }

    @SysLog(action = "createProcessArea", value = "为生产线创建工序区")
    @ApiOperation(value = "为生产线创建工序区")
    @GetMapping("/createProcessArea")
    public Result createProcessArea(Integer processLineId, String processName) {
        // 验证生产线是否存在
        ProcessLine processLine = entityService.getById(processLineId);
        if (null == processLine) {
            return new Result<>(false, "生产线不存在");
        }
        // 检查工序是否已存在
        ProcessTask processTask = processTaskService.getOne(new QueryWrapper<ProcessTask>()
                .eq("product_model", processName)
                .eq("Line_id", processLineId));
        if (null != processTask){
            return new Result<>(false, "该生产线已存在该工序");
        }
        // 创建新的工序任务
        processTask = new ProcessTask();
        processTask.setLineId(processLineId);
        processTask.setProcessName(processName);
        processTask.setStatus("待生产");
        processTask.setCount(0);
        processTask.setProductModel(processLine.getProductModel());
        processTask.setCreatedAt(LocalDateTime.now());
        processTask.setUpdatedAt(LocalDateTime.now());
        processTaskService.save(processTask);
        return new Result<>(true, processTask);
    }

    @SysLog(action = "timeoutProcessLine", value = "暂停执行生产线")
    @ApiOperation(value = "停止执行生产线")
    @GetMapping("/timeoutProcessLine")
    public Result timeoutProcessLine(Integer processLineId) {
        // 获取生产线
        ProcessLine processLine = entityService.getById(processLineId);
        if (processLine == null) {
            return Result.failed("生产线不存在");
        }
        // 更新生产线状态为待生产
        processLine.setStatus("待生产");
        processLine.setUpdatedAt(LocalDateTime.now());
        processLine.setEndTime(LocalDateTime.now());
        processLine.setStartTime(null);
        entityService.updateById(processLine);

        // 更新关联的生产订单
        ProductionOrder productionOrder = productionOrderService
                .getOne(new QueryWrapper<ProductionOrder>().eq("order_byline_id", processLine.getLineId()));
        productionOrder.setOrderBylineId(null);
        productionOrder.setStatus("待排产");
        productionOrder.setUpdatedAt(LocalDateTime.now());

        // 添加中断记录
        processHistoryService.addHistory(productionOrder.getOrderId(), processLine.getLineId(), "中断记录");
        productionOrderService.updateById(productionOrder);
        return new Result<>(true, processLine);
    }
}
